#!/usr/bin/env python

""" Thing web interface. This was based on the blog example from web.py """
import web
import model
import json

import time
import os, os.path
import sys

from Process import Process
from Package import Package
from Wifi import Wifi2

### Url mappings

urls = (
    '/', 'Status',
    '/redeem', 'Redeem',
    '/cura', 'Cura',
    '/opkg', 'Opkg',
    '/wifi', 'Wifi',
    '/systemd', 'Systemd',
    '/octoprint', 'Octoprint',
    '/ajax', 'Ajax'
)


import logging
import logging.handlers

my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address = '/dev/log')
my_logger.addHandler(handler)

### Templates
t_globals = {
    "hostname": model.get_hostname()
}
render = web.template.render('templates', base='base', globals=t_globals)
inner  = web.template.render('templates', base='widget')

class Status:
    def GET(self):
        """ Show status page """
        settings = {
            "ip_addresses": ", ".join(model.get_ips()), 
            "url": str(model.get_hostname())+".local"
        }
        widgets = []#[inner.wifi(), inner.opkg()]
        return render.status(settings, widgets)

class Redeem:
    def GET(self):
        """ Edit config files """
        settings = {
            "local": model.get_file("/etc/redeem/local.cfg"), 
            "printer": model.get_file("/etc/redeem/printer.cfg"),
            "default": model.get_file("/etc/redeem/default.cfg"),
            "printers": {
                "all": model.get_printers(), 
                "current": {
                    "image_name": model.get_current_printer().replace(".cfg", ".jpg"), 
                    "name": model.get_current_printer()
                }
            }
        }    
        printer = {
            "revision": "A4A"
        }
        return render.redeem(settings, printer)
        
class Cura: 
    def GET(self):
        """ Edit Cura files """
        settings = {
            "preferences": model.get_file("/home/root/.cura/dev/preferences.ini"), 
            "config": model.get_file("/etc/cura/printer.ini"),
            "printers": {
                "all": model.get_cura_configs(), 
                "current": {
                    "name": model.get_current_cura_config()
                }
            }

        }    
        return render.cura(settings)

class Opkg: 
    def GET(self):        
        return render.opkg()

class Wifi:
    def GET(self):       
        return render.wifi()

class Systemd:
    def GET(self):
        return render.systemd()

class Octoprint:
    def GET(self):
        return render.octoprint(model.get_hostname()+".local:5000")

class Ajax:
    def POST(self):
        data = web.input()
        func = data.func        
        web.header('Content-Type', 'application/json')

        if func == "systemd_get_processes":
            all_p = Process.get_all()
            return json.dumps({
                "ok": True, 
                "processes": all_p
            })
        elif func == "systemd_get_status":            
            p = Process(data.unit)
            status = p.get_status()
            return json.dumps({
                "ok": True, 
                "status": status, 
                "unit": data.unit
            })
        elif func == "systemd_restart":
            p = Process(data.unit)
            if p.restart():
                return json.dumps({
                    "ok":True, 
                    "unit": data.unit, 
                    "status": p.get_status()
                })
            return json.dumps({"ok":False, "unit": data.unit})
        elif func == "upgrade":
            if programs[data.process]:
                if programs[data.process]["package"].upgrade():
                    return json.dumps({
                        "ok":True, 
                        "status": programs[data.process]["process"].get_status(), 
                        "log": programs[data.process]["process"].get_log(), 
                        "version": programs[data.process]["package"].get_version(),
                        "process": data.process
                    })
            return json.dumps({
                "ok": False, 
                "process": data.process
            })
        elif func == "save_file":            
            if model.save_file(data.filename, data.content):
                return json.dumps({"ok":True})
        elif func == "choose_printer":
            if model.choose_printer(data.filename):
                return json.dumps({
                    "ok":True, 
                    "image_name": data.filename.replace(".cfg", ".jpg"), 
                    "new_config": model.get_file("/etc/redeem/printer.cfg")
                })
        elif func == "cura_choose_config":
            if model.choose_cura_config(data.filename):
                return json.dumps({
                    "ok":True, 
                    "new_config": model.get_file("/etc/cura/printer.ini"),
                    "new_name": model.get_link_filename("/etc/cura/printer.ini").replace("/etc/cura/", "")
                })
        # OPKG 
        elif func == "opkg_install":            
            logging.warning(data["packages"])
            logging.warning(json.loads(data["packages"]))
            if Package.install_selected(json.loads(data["packages"])):
                return json.dumps({
                    "ok":True
                })
        elif func == "opkg_update":
            if Package.update_feed():
                return json.dumps({"ok":True})
        elif func == "opkg_list_upgradable":
            (ok, available) = Package.list_upgradable()
            if not ok: 
                return json.dumps({
                    "ok": False, 
                    "error": available
                })
            return json.dumps({
                "ok": True, 
                "packages_available": bool(len(available) > 0), 
                "opkgs": available, 
                "last_updated": Package.last_updated()
            })
        elif func == "opkg_last_updated":
            return json.dumps({
                "ok": True, 
                "last_updated": Package.last_updated()
            })
        elif func == "opkg_check_log":
            return json.dumps({
                "ok": True, 
                "install_log": Package.get_install_log()
            })
        elif func == "opkg_info":            
            return json.dumps({
                "ok": True, 
                "info": Package.info(data.name)
            })
        # Wifi 
        elif func == "wifi_get_ssids":
            if Wifi2.scan():
               return json.dumps({
                    "ok":True, 
                    "ssids": Wifi2.get_ssids()
                })
        elif func == "wifi_connect":
            wifi = Wifi2(data.id)
            if not wifi.id_valid():
                return json.dumps({
                    "ok": False, 
                    "error": "supplied Connman ID is not valid"
                })
            wifi.connect()
            if not wifi.is_connected():
                 return json.dumps({
                    "ok": False, 
                    "error": "Unable to connect to ID"
                })
            return json.dumps({
                "ok":True, 
                "ssids": Wifi2.get_ssids()
            })
        elif func == "wifi_configure":
            wifi = Wifi2(data.id)
            if not wifi.id_valid():
                return json.dumps({
                    "ok": False, 
                    "error": "supplied Connman ID is not valid"
                })
            wifi.write_config(data.id, data.ssid, data.passwd)
            return json.dumps({
                "ok":True, 
                "ssids": Wifi2.get_ssids()
            })
        else:
            return json.dumps({"ok":False, "error": "Unknown function"})        
        return json.dumps({"ok":False})

app = web.application(urls, globals())

if __name__ == '__main__':
    app.run()
